let Vue = null;
class Store{
  constructor(options){
    // options {state,mutations,...}
    let vm = new Vue({
      data:{
        state:options.state
      }
    })
    this.state = vm.state
    // this.state = options.state
    this.mutations = {};// 用来存储对应的mutations // {f1:()=>,f2:()=>{}}
    let mutations = options.mutations || {};// {f1(){},f2(){}}
    Object.keys(mutations).forEach(key=>{
      this.mutations[key] = (qqq)=>{
        mutations[key].call(this,this.state,qqq)
      }
    })

    this.actions = {};
    let actions = options.actions || {};
    Object.keys(actions).forEach(key=>{
      this.actions[key] = (aaa)=>{
        actions[key].call(this,this,aaa)
      }
    })

    this.getters = {};
    let getters = options.getters || {};
    Object.keys(getters).forEach(key=>{
      Object.defineProperty(this.getters,key,{
        get:()=>{
          return getters[key].call(this,this.state)
        }
      })
    })
  }
  commit(type,qqq){
    //this.$store.commit('f1;,100)
    this.mutations[type](qqq)// this.mutations.f1(100)
  }
  dispatch(type,aaa){
    this.actions[type](aaa)
  }
}
function install(_vue){
  // vuex是怎么把￥store挂在到了每一个实例上去？ 借助了 混入 mixin
  if(Vue&& _vue == Vue){
    return this
  }
  Vue = _vue;
  Vue.mixin({
    // 有多少组件 这个钩子就执行多少次
    beforeCreate() {
      // 这个点代码就实现了每一个组件上 都有一个$store属性
      if(this.$options.store){
        // 说的就是 new Vue({}) 传递的那些属性
        // this.$option.store 指的就是我们 vuex产生的哪个实例
        this.$store = this.$options.store
      }else if(this.$parent){
        this.$store = this.$parent.$store
      }
    }
  })

}
export function mapState(ary=[]){
  let obj = {}
  ary.forEach(key=>{
    obj[key] = function(){
      // this 是组件
      return this.$store.state[key]
    }
  })
  return obj
}
export  function mapGetters(ary){
  let obj = {}
  ary.forEach(key=>{
    obj[key] = function(){
      // this 是组件
      return this.$store.getters[key]
    }
  })
  return obj
}
export function mapMutations(ary) {
  let obj = {}
  ary.forEach(key=>{
    obj[key] = function (params) {
      // this 是组件
      return this.$store.commit(key,params)
    }
  })
  console.log(obj)
  return obj
}
export function mapActions(ary) {
  let obj = {}
  ary.forEach(key=>{
    obj[key] = function (params) {
      // this 是组件
      return this.$store.dispatch(key,params)
    }
  })
  return obj
}

export default {
  install,
  Store,
  // mapState,
  // mapMutations,
  // mapActions,
  // mapGetters
}